#ifndef MULTI_MEMORY_POOL_HPP
#define MULTI_MEMORY_POOL_HPP

#include <iostream>
#include <map>
#include <vector>
#include <cassert>
#include <cmath>
#include <mutex>
#include <algorithm>
#include "web_data.h"

// 单级内存池
class MemoryPool {
private:
    struct Block {
        Block* next;
    };

    struct Chunk {
        Chunk* next;
    };

    Chunk* chunkHead;
    Block* freeBlockHead;
    size_t blockSize;
    size_t blocksPerChunk;

    void allocateChunk() {
        size_t chunkSize = blockSize * blocksPerChunk;
        Chunk* newChunk = reinterpret_cast<Chunk*>(new char[chunkSize]);
        newChunk->next = chunkHead;
        chunkHead = newChunk;

        char* start = reinterpret_cast<char*>(newChunk);
        for (size_t i = 0; i < blocksPerChunk; ++i) {
            Block* block = reinterpret_cast<Block*>(start + i * blockSize);
            block->next = freeBlockHead;
            freeBlockHead = block;
        }
    }

public:
    explicit MemoryPool(size_t blockSize, size_t blocksPerChunk = 2)
        : chunkHead(nullptr), freeBlockHead(nullptr), blockSize(blockSize), blocksPerChunk(blocksPerChunk) {
        assert(blockSize >= sizeof(Block));
        allocateChunk();
    }

    ~MemoryPool() {
        while (chunkHead) {
            Chunk* nextChunk = chunkHead->next;
            delete[] reinterpret_cast<char*>(chunkHead);
            chunkHead = nextChunk;
        }
    }

    void* allocate() {
        if (!freeBlockHead) {
            allocateChunk();
        }
        Block* allocatedBlock = freeBlockHead;
        freeBlockHead = freeBlockHead->next;
        return allocatedBlock;
    }

    void deallocate(void* ptr) {
        Block* block = reinterpret_cast<Block*>(ptr);
        block->next = freeBlockHead;
        freeBlockHead = block;
    }
};

// 多级内存池（单例模式，线程安全）
class MultiSizeMemoryPool {
public:
    // 禁止拷贝构造和赋值操作
    MultiSizeMemoryPool(const MultiSizeMemoryPool&) = delete;
    MultiSizeMemoryPool& operator=(const MultiSizeMemoryPool&) = delete;

    // 获取单例实例
    static MultiSizeMemoryPool& getInstance() {
        static MultiSizeMemoryPool instance; // C++11保证线程安全的局部静态变量
        return instance;
    }

    bool insertMemBlockData(const char *pBody, size_t len, std::vector<MemBlock> &vec)
    {
        if(!pBody || len < 1)
        {
            return false;
        }
        //找到未填满的Index
        size_t index = (size_t)-1;
        size_t vecLen = vec.size();
        for(size_t i = 0; i < vecLen; i++)
        {
            if(vec[i].newSize > vec[i].size)
            {
                index = i;
                break;
            }
        }
        if(index == static_cast<size_t>(-1))
        {
            return false;
        }
        //把未满的填充满
		size_t blockSize = std::min(len, vec[index].newSize - vec[index].size);
        char *pTmpStr = (char*)pBody;
        char *pDest = vec[index].ptr + vec[index].size;
		memcpy(pDest, pTmpStr, blockSize);
		pTmpStr += blockSize;
		len -= blockSize;
		vec[index].size += blockSize;
        index += 1;

        while (len > 0 && index < vecLen)
        {
            size_t blockSize = std::min(vec[index].newSize, len);
            memcpy(vec[index].ptr, pTmpStr, blockSize);
            pTmpStr += blockSize;
            len -= blockSize;
			vec[index].size = blockSize;
            index++;
        }

        return true;
    }
    //需要自己填充数据
    void newMemBlock(size_t size, std::vector<MemBlock> &blocks)
    {
        std::lock_guard<std::mutex> lock(mutex_); // 线程安全保护
        size_t alignedSize = alignSize(size);
        size_t remaining = size;
        while (remaining > 0) {
            size_t blockSize = std::min(alignedSize, remaining);
            size_t newSize = alignSize(blockSize);
            if (pools.find(newSize) == pools.end()) 
            {
                pools[newSize] = new MemoryPool(newSize);
            }
            void* block = pools[newSize]->allocate();
            blocks.push_back({(char*)block, 0, newSize}); // 记录指针和大小
            remaining -= blockSize;
        }
    }

    //申请内存并填充数据
    void newMemBlockAndInsertData(const char* pBody, size_t size, std::vector<MemBlock> &blocks) {
        std::lock_guard<std::mutex> lock(mutex_); // 线程安全保护
        size_t alignedSize = alignSize(size);
        size_t remaining = size;
        char *pTmpStr = (char*)pBody;
        while ((remaining > 0) && pTmpStr) {
            size_t blockSize = std::min(alignedSize, remaining);
            size_t newSize = alignSize(blockSize);
            if (pools.find(newSize) == pools.end()) 
            {
                pools[newSize] = new MemoryPool(newSize);
            }
            void* block = pools[newSize]->allocate();
            memcpy(block, pTmpStr, blockSize);
            pTmpStr += blockSize;
            blocks.push_back({(char*)block, blockSize, newSize}); // 记录指针和大小
            remaining -= blockSize;
        }
    }
    //释放内存
    void deleteMemBlock(std::vector<MemBlock>& blocks) {
        std::lock_guard<std::mutex> lock(mutex_); // 线程安全保护
        for (const auto& block : blocks) {
            deallocate(block.ptr, block.size);
        }
        blocks.clear();
    }

private:
    MultiSizeMemoryPool() = default; // 私有构造函数
    ~MultiSizeMemoryPool() {
        for (auto& pair : pools) {
            delete pair.second;
        }
    }

    void* allocate(size_t size) {
        size_t alignedSize = alignSize(size);
        if (pools.find(alignedSize) == pools.end()) {
            pools[alignedSize] = new MemoryPool(alignedSize);
        }
        return pools[alignedSize]->allocate();
    }

    void deallocate(void* ptr, size_t size) {
        size_t alignedSize = alignSize(size);
        assert(pools.find(alignedSize) != pools.end() && "Trying to deallocate to a non-existent pool!");
        pools[alignedSize]->deallocate(ptr);
    }

    size_t alignSize(size_t size) {
        size_t aligned = 256; // 起始对齐大小为256
        while (aligned < size) {
            aligned *= 4; // 按4的倍数增长
        }
        return aligned > 4 * 1024 * 1024 ? 4 * 1024 * 1024 : aligned; // 最大对齐到4MB
    }

private:
    std::map<size_t, MemoryPool*> pools; // 内存池集合
    std::mutex mutex_;                   // 线程安全锁
};

#endif
